

import 'package:flutter/material.dart';
import 'package:flutter_boost/boost_navigator.dart';
// 语音交互界面
class SpeakPage extends StatefulWidget {

  @override
  _SpeakPageState createState() => _SpeakPageState();
}

class _SpeakPageState extends State<SpeakPage> with SingleTickerProviderStateMixin {

  String speakTips = '长按说话';
  Animation<double> animation;
  AnimationController controller;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    controller = AnimationController(vsync: this, duration: Duration(seconds: 1));
    animation = CurvedAnimation(parent: controller, curve: Curves.easeIn)..addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        controller.forward();
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    // 销毁
    controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
          padding: const EdgeInsets.all(30),
          child: Center(
            child: Column(
              // 在两边
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                _topItem(),
                _bottomItem()
              ],
            ),
          ),
        )
    );
  }

  /// 顶部的内容
  _topItem() {
    return Column(
      children: const [
        Padding(
            padding: EdgeInsets.fromLTRB(0, 30, 0, 30),
          child: Text('你可以这样说', style: TextStyle(fontSize: 16, color: Colors.black54),),
        ),
        Text(
            '故宫门票\n北京一日游\n迪士尼乐园',
          textAlign: TextAlign.center,
          style: TextStyle(fontSize: 15,
          color: Colors.grey),
        )
      ],
    );
  }

  /// 底部的内容
  _bottomItem() {
    return FractionallySizedBox(
      widthFactor: 1,
      child: Stack(
        children: [
          GestureDetector(
            onTapDown: (TapDownDetails details) {
              print("按下去");
            },
            onTapUp: (TapUpDetails details) {
              print("按下去松开");
            },
            onTapCancel: () {
              print("按下去取消");
            },
            child: Center(
              child: Column(
                children: [
                  Padding(
                    padding: EdgeInsets.all(10),
                    child: Text(speakTips, style: TextStyle(color: Colors.blue, fontSize: 12),),
                  ),
                  Stack(
                    children: [
                      Container(
                        // 占坑，避免动画执行过程中导致父布局大小变化
                        height: MIC_SIZE,
                        width: MIC_SIZE,
                      ),
                      Center(
                        child: animation != null ? AnimatedMic(animation: animation,) : null,
                      )
                    ],
                  )
                ],
              ),
            ),
          ),
          Positioned(
              right: 0,
              bottom: 20,
              child: GestureDetector(
                onTap: () {
                  setState(() {
                    BoostNavigator.instance.pop();
                  });
                },
                child: const Icon(
                  Icons.close,
                  size: 30,
                  color: Colors.grey,
                ),
              )
          )
        ],
      ),
    );
  }
}

const double MIC_SIZE = 80;
class AnimatedMic extends AnimatedWidget {
  static final _opacityTween = Tween<double>(begin: 1, end: 0.5);
  static final _sizeTween = Tween<double>(begin: MIC_SIZE, end: MIC_SIZE - 20);

  const AnimatedMic({Key key, Animation<double> animation}) : super(key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Opacity(
      opacity: _opacityTween.evaluate(animation),
      child: Container(
        height: _sizeTween.evaluate(animation),
        width: _sizeTween.evaluate(animation),
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(MIC_SIZE / 2),
        ),
        child: const Icon(
          Icons.mic,
          color: Colors.white,
          size: 30,
        ),
      ),
    );
  }
}















